import axios from 'axios'
import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/ruoyi'
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import useUserStore from '@/store/modules/user'
import { getConfigFileName } from '@/utils/env'

let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: import.meta.env.VITE_APP_BASE_API,
  // 超时
  timeout: 10000,
  // 添加默认cancelToken
  cancelToken: new axios.CancelToken(function (cancel) {
    // 保存 cancel 函数，以便可以在需要时调用它
    service.cancelRequest = cancel;
  })
})

// request拦截器
service.interceptors.request.use(config => {
  // 添加cancelToken
  if (!config.cancelToken) {
    config.cancelToken = new axios.CancelToken(function (cancel) {
      // 可以用于取消请求
      config._cancel = cancel;
    });
  }

  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  const token = getToken()
  if (token && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + token
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
    const requestObj = {
      url: config.url,
      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
      time: new Date().getTime()
    }
    const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
    const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
    if (requestSize >= limitSize) {
      console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制，无法进行防重复提交验证。')
      return config
    }
    const sessionObj = cache.session.getJSON('sessionObj')
    const p = new Promise(resolve => {
      if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
        cache.session.setJSON('sessionObj', requestObj)
        resolve()
      } else {
        const s_p = sessionObj.time + 10000
        if (s_p > new Date().getTime()) {
          ElMessageBox.confirm('数据重复提交，是否继续?', '警告', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            cache.session.setJSON('sessionObj', requestObj)
            resolve()
          }).catch(() => {
            resolve()
          })
        } else {
          cache.session.setJSON('sessionObj', requestObj)
          resolve()
        }
      }
    })
    return p
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// response 拦截器
service.interceptors.response.use(res => {
  // 未设置状态码则默认成功状态
  const code = res.data.code || 200;
  // 获取错误信息
  const msg = errorCode[code] || res.data.msg || errorCode['default']
  // 二进制数据直接返回
  if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {
    return res.data
  }
  // 401: 未登录或未授权
  if (code === 401) {
    if (!isRelogin.show) {
      isRelogin.show = true;
      ElMessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        isRelogin.show = false;
        useUserStore().logOut().then(() => {
          location.href = '/index';
        })
      }).catch(() => {
        isRelogin.show = false;
      });
    }
    return Promise.reject('无效的会话，或者会话已过期，请重新登录。')
  } else if (code === 500) {
    ElMessage.error(msg)
    return Promise.reject(new Error(msg))
  } else if (code === 601) {
    ElMessage.warning(msg)
    return Promise.reject(new Error(msg))
  } else if (code !== 200) {
    ElNotification.error({
      title: msg
    })
    return Promise.reject('error')
  } else {
    return res.data
  }
},
error => {
  console.log('err' + error)
  // 检查是否是取消请求的错误
  if (axios.isCancel(error)) {
    console.log('请求被取消:', error.message);
    return Promise.reject(new Error('请求已取消'));
  }
  
  // 检查是否是cancelToken相关错误
  if (error.message && error.message.includes('cancelToken')) {
    console.error('cancelToken错误:', error);
    return Promise.reject(new Error('请求配置错误，请刷新页面重试'));
  }
  
  ElMessage({
    message: error.message,
    type: 'error',
    duration: 5 * 1000
  })
  return Promise.reject(error)
})

// 通用下载方法
export function download(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      ElMessage.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    ElMessage.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close();
  })
}

// 通用下载方法
export function download2(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      ElMessage.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    ElMessage.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close();
  })
}

// OCR API 请求方法 - 使用原生 fetch 避免 cancelToken 问题
export function fetchOcr(url, data) {
  const baseURL = import.meta.env.VITE_APP_BASE_API;
  const token = getToken();
  
  console.log('使用 fetchOcr 发送请求:', url);
  console.log('请求 URL:', baseURL + url);
  
  // 创建FormData
  const formData = new FormData();
  formData.append('imageBase64', data);
  
  // 两种方式尝试 - 先尝试使用FormData
  return fetch(baseURL + url, {
    method: 'POST',
    headers: {
      'Authorization': token ? 'Bearer ' + token : ''
      // 不设置Content-Type，让浏览器自动设置multipart/form-data边界
    },
    body: formData
  })
  .then(response => {
    console.log('收到 OCR 响应:', response.status, response.statusText);
    if (!response.ok) {
      // 如果FormData方式失败，尝试使用纯文本方式
      if (response.status === 500 || response.status === 415) {
        console.log('FormData方式失败，尝试使用纯文本方式');
        return fetch(baseURL + url, {
          method: 'POST',
          headers: {
            'Content-Type': 'text/plain',
            'Authorization': token ? 'Bearer ' + token : ''
          },
          body: data
        });
      }
      throw new Error(`请求失败: ${response.status} ${response.statusText}`);
    }
    return response;
  })
  .then(response => {
    console.log('收到 OCR 响应(可能是重试后):', response.status, response.statusText);
    if (!response.ok) {
      throw new Error(`请求失败: ${response.status} ${response.statusText}`);
    }
    
    // 尝试解析 JSON
    return response.text().then(text => {
      console.log('原始响应文本:', text.substring(0, 150) + (text.length > 150 ? '...' : ''));
      try {
        return JSON.parse(text);
      } catch (error) {
        console.error('JSON解析错误:', error, '原始文本:', text.substring(0, 100));
        return { code: 500, msg: '响应格式无效' };
      }
    });
  })
  .then(data => {
    console.log('OCR 请求成功, 响应:', data);
    // 模拟与 axios 响应格式相同的结构
    if (data && data.code !== undefined) {
      if (data.code === 200) {
        return data;
      } else {
        const msg = errorCode[data.code] || data.msg || errorCode['default'];
        console.warn('OCR 请求返回错误码:', data.code, msg);
        ElMessage.error(msg);
        return Promise.reject(new Error(msg));
      }
    }
    return { code: 200, data };
  })
  .catch(error => {
    console.error('OCR请求错误:', error);
    ElMessage.error(error.message || '请求失败');
    return Promise.reject(error);
  });
}

export default service
